package com.guodi.map.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guodi.common.utils.UuidUtil;
import com.guodi.core.secure.utils.AuthUtil;
import com.guodi.map.constant.MapConst;
import com.guodi.map.entity.MapDatabaseSource;
import com.guodi.map.mapper.MapDatabaseSourceMapper;
import com.guodi.map.service.IMapDatabaseSourceService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.UnsupportedEncodingException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Date;
import java.util.Objects;

/**
* 数据源 服务实现类
* @作者：  陈宏成
* @日期： 2022-01-18
*/
@Service
@Slf4j
public class MapDatabaseSourceServiceImpl extends ServiceImpl<MapDatabaseSourceMapper, MapDatabaseSource> implements IMapDatabaseSourceService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean save(MapDatabaseSource entity) {
        if (StringUtils.isBlank(entity.getId())){
            entity.setId(UuidUtil.get32UUID());
        }
        if (StringUtils.isBlank(entity.getCreator())){
            entity.setCreator(AuthUtil.getUserId().toString());
        }
        if (Objects.isNull(entity.getCreateTime())){
            entity.setCreateTime(new Date());
        }
        return super.save(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateById(MapDatabaseSource entity) {
        entity.setModifier(AuthUtil.getUserId().toString());
        entity.setModifyTime(new Date());
        // 修改
        MapDatabaseSource oldEntity = this.getById(entity.getId());
        LambdaUpdateWrapper<MapDatabaseSource> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.setEntity(oldEntity);
        boolean update = this.update(entity ,updateWrapper);
        return update;
    }

    @Override
    public boolean testDB(MapDatabaseSource databaseSource) throws ClassNotFoundException{
        String dbType= MapConst.POSTGRESQL_TYPE;
        if(MapConst.ORACLE_TYPE.equalsIgnoreCase(databaseSource.getType())){
            dbType= MapConst.ORACLE_TYPE;
        }
        String url=null;
        String driverClass=null;
        if(MapConst.POSTGRESQL_TYPE.equalsIgnoreCase(dbType)){
            driverClass="org.postgresql.Driver";
            url ="jdbc:postgresql://"+databaseSource.getIp()+":"+databaseSource.getPort()+"/"+databaseSource.getInstance();
        }else if(MapConst.ORACLE_TYPE.equalsIgnoreCase(dbType)){
            driverClass="oracle.jdbc.driver.OracleDriver";
            url ="jdbc:oracle:thin:@"+databaseSource.getIp()+":"+databaseSource.getPort()+":"+databaseSource.getInstance();
        }
        String password =databaseSource.getPassword();
        Decoder decoder = Base64.getDecoder();
        byte[] decode = decoder.decode(password);
        String dePassword="";
        try {
            dePassword = new String(decode,"utf-8");
        } catch (UnsupportedEncodingException e) {
            log.info("password UnsupportedEncodingException:{}",e.getMessage());
            log.info(e.getMessage(),e);
        }
        Connection connection =null;
        try {
            Class.forName(driverClass);
            connection =DriverManager.getConnection(url, databaseSource.getUsername(), dePassword);
            return true;
        } catch (SQLException e){
            log.info("getConnection error:{}",e.getMessage());
            log.info(e.getMessage(),e);
        }catch (ClassNotFoundException e){
            log.info("driverClass ClassNotFoundException:{}",e.getMessage());
            log.info(e.getMessage(),e);
            throw new ClassNotFoundException("driverClass ClassNotFoundException");
        }finally {
            if(connection!=null){
                try {
                    connection.close();
                } catch (SQLException e) {
                    log.info("connection close error:{}",e.getMessage());
                    log.info(e.getMessage(),e);
                }
            }
        }
        return false;
    }
}
